package com.eparking;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JOptionPane;

import com.alibaba.fastjson.JSONObject;
import com.eparking.HCNetSDK.NET_DVR_ALARMER;
import com.eparking.HCNetSDK.NET_DVR_DEVICEINFO_V40;
import com.eparking.HCNetSDK.NET_DVR_PLATE_RESULT;
import com.eparking.HCNetSDK.NET_DVR_SETUPALARM_PARAM;
import com.eparking.HCNetSDK.NET_DVR_USER_LOGIN_INFO;
import com.eparking.HCNetSDK.NET_ITS_PARK_VEHICLE;
import com.eparking.HCNetSDK.NET_ITS_PLATE_RESULT;
import com.sun.jna.NativeLong;
import com.sun.jna.Pointer;

public class HikVisionService {
   
    static HCNetSDK hCNetSDK = HCNetSDK.INSTANCE;
    NET_DVR_DEVICEINFO_V40 m_registerInfo;
    NET_DVR_USER_LOGIN_INFO m_loginInfo;
    static String m_sDeviceIP = "192.168.1.64";//已登录设备的IP地址
    static String m_sUsername = "admin";//设备用户名
    static String m_sPassword = "zyb110220";//设备密码,默认的好像是12345
    static short m_sPort = 8000;//端口号，这是默认的
    public NativeLong lUserID;//用户句柄
    public NativeLong lAlarmHandle;//报警布防句柄
    public int lListenHandle;//报警监听句柄
    public NativeLong RemoteConfig;
    
    public static int code = 5;
//    static String m_sDeviceIP = EparkingConfig.leftDeviceIP;//已登录设备的IP地址
//    static String m_sUsername = EparkingConfig.leftUserName;//设备用户名
//    static String m_sPassword = EparkingConfig.leftPassword;//设备密码,默认的好像是12345
//    static String sendUrl = EparkingConfig.sendUrl; //发送接口地址
    //撤防
    public void CloseAlarmChan() {
        //报警撤防
        if (lAlarmHandle.intValue() > -1) {
            if (hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle.intValue())) {
                System.out.println("撤防成功");
                lAlarmHandle = new NativeLong(-1);
            }
        }
    }

    public  void initMemberFlowUpload(int remainMinuteTime,String ip,String userName,String password) throws InterruptedException {
    	m_sDeviceIP = ip;
    	m_sUsername = userName;
    	m_sPassword = password;
//    	System.out.println("m_sDeviceIP="+m_sDeviceIP);
//        System.out.println("m_sUsername="+m_sUsername);
//        System.out.println("m_sPassword="+m_sPassword);
//        System.out.println("sendUrl="+sendUrl);
    	// 初始化
        Boolean flag = hCNetSDK.NET_DVR_Init();
        if (flag){
            System.out.println("初始化成功");
        }else{
            System.out.println("初始化失败");
        }
        //设置连接时间与重连时间
        hCNetSDK.NET_DVR_SetConnectTime(2000, 1);
        hCNetSDK.NET_DVR_SetReconnect(100000, true);
        //设备信息, 输出参数
        NET_DVR_DEVICEINFO_V40 m_strDeviceInfo = new NET_DVR_DEVICEINFO_V40();
        NET_DVR_USER_LOGIN_INFO m_strLoginInfo = new NET_DVR_USER_LOGIN_INFO();
        // 注册设备-登录参数，包括设备地址、登录用户、密码等
        m_strLoginInfo.sDeviceAddress = new byte[hCNetSDK.NET_DVR_DEV_ADDRESS_MAX_LEN];
        System.arraycopy(m_sDeviceIP.getBytes(), 0, m_strLoginInfo.sDeviceAddress, 0, m_sDeviceIP.length());
        m_strLoginInfo.sUserName = new byte[hCNetSDK.NET_DVR_LOGIN_USERNAME_MAX_LEN];
        System.arraycopy(m_sUsername.getBytes(), 0, m_strLoginInfo.sUserName, 0, m_sUsername.length());
        m_strLoginInfo.sPassword = new byte[hCNetSDK.NET_DVR_LOGIN_PASSWD_MAX_LEN];
        System.arraycopy(m_sPassword.getBytes(), 0, m_strLoginInfo.sPassword, 0, m_sPassword.length());
        m_strLoginInfo.wPort = m_sPort;
        m_strLoginInfo.bUseAsynLogin = false; //是否异步登录：0- 否，1- 是
        m_strLoginInfo.write();

        //设备信息, 输出参数
         int lUserID = hCNetSDK.NET_DVR_Login_V40(m_strLoginInfo,m_strDeviceInfo);
//        System.out.println("lUserID.size-->" + lUserID);
        if(lUserID< 0){
            System.out.println("hCNetSDK.NET_DVR_Login_V30()"+"\n" +hCNetSDK.NET_DVR_GetErrorMsg(null));
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }
      
        //设置报警回调函数
        if (!hCNetSDK.NET_DVR_SetDVRMessageCallBack_V31(this::MsesGCallBack,null )){
            System.out.println("设置回调函数失败"+hCNetSDK.NET_DVR_GetLastError());
            return;
        }else {
            System.out.println("设置回调函数成功");
        }
        //启用布防
       NET_DVR_SETUPALARM_PARAM lpSetupParam = new NET_DVR_SETUPALARM_PARAM();
        lpSetupParam.dwSize = 0;
        lpSetupParam.byLevel = 1;//布防优先级：0- 一等级（高），1- 二等级（中）
        lpSetupParam.byAlarmInfoType = 1;//上传报警信息类型: 0- 老报警信息(NET_DVR_PLATE_RESULT), 1- 新报警信息(NET_ITS_PLATE_RESULT)
        int lAlarmHandle = hCNetSDK.NET_DVR_SetupAlarmChan_V41(lUserID,lpSetupParam);
        if (lAlarmHandle< 0)
        {
            System.out.println("NET_DVR_SetupAlarmChan_V41 error, %d\n"+hCNetSDK.NET_DVR_GetLastError());
            hCNetSDK.NET_DVR_Logout(lUserID);
            hCNetSDK.NET_DVR_Cleanup();
            return;
        }
        System.out.println("布防成功,开始监测车辆");

        //启动监听----------------------------------------------
        int iListenPort = 8100;
        String m_sListenIP = "192.168.1.64";
       
        lListenHandle = hCNetSDK.NET_DVR_StartListen_V30(m_sListenIP, (short) iListenPort, this::MsesGCallBack, null);
        if(lListenHandle < 0)
        {
//            JOptionPane.showMessageDialog(null, "启动监听失败，错误号:" +  hCNetSDK.NET_DVR_GetLastError());
        }
        else
        {
            JOptionPane.showMessageDialog(null, "启动监听成功");
        }

        //-------------------识别任务提交-----------------


        Thread.sleep(200000); //等待接收数据

        //等待过程中，如果设备上传报警信息，在报警回调函数里面接收和处理报警信息
        Timer timer = new Timer();// 实例化Timer类
        timer.schedule(new TimerTask() {
            public void run() {
                //撤销布防上传通道
                if (! hCNetSDK.NET_DVR_CloseAlarmChan_V30(lAlarmHandle))
                {
                    System.out.println("! hCNetSDK.NET_DVR_CloseAlarmChan_V31(lAlarmHandle)\n"+ hCNetSDK.NET_DVR_GetLastError() +"\n" +hCNetSDK.NET_DVR_GetErrorMsg(null) );
                    hCNetSDK.NET_DVR_Logout(lUserID);
                    hCNetSDK. NET_DVR_Cleanup();
                    return;
                }

                //注销用户
                hCNetSDK.NET_DVR_Logout(lUserID);
                //释放SDK资源
                hCNetSDK.NET_DVR_Cleanup();
                this.cancel();
                System.gc();//主动回收垃圾
            }
        }, remainMinuteTime * 60 * 1000 );// 这里毫秒
    }

  


    public boolean MsesGCallBack(int lCommand, NET_DVR_ALARMER pAlarmer, Pointer pAlarmInfo, int dwBufLen, Pointer pUser) {
        System.out.println("〈－－进入回调,开始识别车牌－－〉");
        String  filePath = System.getProperty("user.dir")+ "\\camera.properties";
//        String filePath = "D:\\wlgl-workspace\\eparking\\camera.properties";

        String sendUrl = PropertiesTool.GetValueByKey(filePath,"sendUrl");
        try {
            String sAlarmType = new String();
            String[] newRow = new String[3];
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String[] sIP = new String[2];
//            System.out.println("lCommand="+lCommand);
//            DefaultTableModel alarmTableModel = ((DefaultTableModel) jTableAlarm.getModel());//获取表格模型
            switch (lCommand) {
//                case COMM_ITS_PARK_VEHICLE:
                case 0x3056:   //停车场数据上传
                    NET_ITS_PARK_VEHICLE strItsParkVehicle = new NET_ITS_PARK_VEHICLE();
                    strItsParkVehicle.write();
                    Pointer pItsParkVehicle = strItsParkVehicle.getPointer();
                    pItsParkVehicle.write(0, pAlarmInfo.getByteArray(0, strItsParkVehicle.size()), 0, strItsParkVehicle.size());
                    strItsParkVehicle.read();
                    String srtParkingNo = null;
                    String srtPlate = null;
                    try {
                        srtParkingNo = new String(strItsParkVehicle.byParkingNo).trim(); //车位编号
                        srtPlate = new String(strItsParkVehicle.struPlateInfo.sLicense, "GBK").trim(); //车牌号码
                        sAlarmType = sAlarmType + ",停产场数据,车位编号：" + srtParkingNo + ",车位状态："
                                + strItsParkVehicle.byLocationStatus + ",车牌：" + srtPlate;
                        System.out.println(sAlarmType + "sAlarmType");
                    } catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    //增加——————————————
                  

//
                    break;
//                case COMM_UPLOAD_PLATE_RESULT:
                case 0x2800:	//交通抓拍结果上传
                    NET_DVR_PLATE_RESULT strPlateResult = new NET_DVR_PLATE_RESULT();
                    strPlateResult.write();
                    Pointer pPlateInfo = strPlateResult.getPointer();
                    pPlateInfo.write(0, pAlarmInfo.getByteArray(0, strPlateResult.size()), 0, strPlateResult.size());
                    strPlateResult.read();
                    try {
                        String srt3=new String(strPlateResult.struPlateInfo.sLicense,"GBK");
                        sAlarmType = sAlarmType + "：交通抓拍上传，车牌："+ srt3;
                    }
                    catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    newRow[0] = dateFormat.format(new Date());
                    //报警类型
                    newRow[1] = sAlarmType;
                    //报警设备IP地址
                    sIP = new String(pAlarmer.sDeviceIP).split("\0", 2);
                    newRow[2] = sIP[0];
//                    alarmTableModel.insertRow(0, newRow);

                    if(strPlateResult.dwPicLen>0)
                    {
                        SimpleDateFormat sf = new SimpleDateFormat("yyyyMMddHHmmss");
                        String newName = sf.format(new Date());
                        FileOutputStream fout;
                        try {
                            fout = new FileOutputStream(".\\pic\\"+ new String(pAlarmer.sDeviceIP).trim() + "_"
                                    + newName+"_plateResult.jpg");
                            //将字节写入文件
                            long offset = 0;
                            ByteBuffer buffers = strPlateResult.pBuffer1.getByteBuffer(offset, strPlateResult.dwPicLen);
                            byte [] bytes = new byte[strPlateResult.dwPicLen];
                            buffers.rewind();
                            buffers.get(bytes);
                            fout.write(bytes);
                            fout.close();
                        } catch (FileNotFoundException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                    break;
//                case COMM_ITS_PLATE_RESULT:
                case 0x3050:	//交通抓拍的终端图片上传
                    NET_ITS_PLATE_RESULT strItsPlateResult = new NET_ITS_PLATE_RESULT();
                    strItsPlateResult.write();
                    Pointer pItsPlateInfo = strItsPlateResult.getPointer();
                    pItsPlateInfo.write(0, pAlarmInfo.getByteArray(0, strItsPlateResult.size()), 0, strItsPlateResult.size());
                    strItsPlateResult.read();
                    try {
                        String srt3=new String(strItsPlateResult.struPlateInfo.sLicense,"GBK");
                        sAlarmType = sAlarmType + ",车辆类型："+strItsPlateResult.byVehicleType + ",交通抓拍上传，车牌："+ srt3;
                        Map<String,String> paramMap = new HashMap<String,String>();
                        paramMap.put("type", strItsPlateResult.byVehicleType+"".trim());
                        srt3 = srt3.substring(1, srt3.length());
                        paramMap.put("plateNumber", srt3.trim());
//                        HttpClientUtil.postJson("http://localhost/sys/vehicle/plateNumber", JSONObject.toJSONString(paramMap));
                        HttpClientUtil.postJson(sendUrl+"?code="+code, JSONObject.toJSONString(paramMap));
                        System.out.println("-----已成功发送车牌信息－－－－－");
                    }
                    catch (UnsupportedEncodingException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }

                    break;
            }
            System.out.println("识别信息：---》" +sAlarmType);
            //报警类型
            //报警设备IP地址
            //sIP = new String(strPDCResult.struDevInfo.struDevIP.sIpV4).split("\0", 2);
            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }


    public static void main(String[] args) throws InterruptedException {
        HikVisionService hiKService = new HikVisionService();
//        String filePath = "D:\\wlgl-workspace\\eparking\\camera.properties";
		String  filePath = System.getProperty("user.dir")+ "\\camera.properties";
		Map<String, String> paramMap = new HashMap<String,String>();
		try {
			paramMap = PropertiesTool.GetAllProperties(filePath);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		String inIp = paramMap.get("in.DeviceIP");
		String inName = paramMap.get("in.UserName");
		String inPwd = paramMap.get("in.Password");
		
		String outIp = paramMap.get("out.DeviceIP");
		String outName = paramMap.get("out.UserName");
		String outPwd = paramMap.get("out.Password");
		
		int minute = Integer.parseInt(paramMap.get("minute")!=null?paramMap.get("minute"):"30");
		
		if(inIp!=null && !inIp.equals("") && inName!=null && !inName.equals("") && inPwd!=null && !inPwd.equals("")) {
			 hiKService.code = 5;
			 hiKService.initMemberFlowUpload(minute,inIp,inName,inPwd);
		}
		
		if(outIp!=null && !outIp.equals("") && outName!=null && !outName.equals("") && outPwd!=null && !outPwd.equals("")) {
			hiKService.code = 6;
			hiKService.initMemberFlowUpload(minute,outIp,outName,outPwd);
		}
       
    }

}


